"""
数据库模型定义模块
定义项目中使用的各个数据模型
"""

# 导入SQLAlchemy相关组件
from sqlalchemy import create_engine, Column, Integer, String, DateTime, Text, Float
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from datetime import datetime
import os

# 从环境变量获取数据库配置信息
MYSQL_USER = os.getenv('MYSQL_USER', 'root')
MYSQL_PASS = os.getenv('MYSQL_PASS', 'password')
MYSQL_HOST = os.getenv('MYSQL_HOST', 'localhost')
MYSQL_PORT = os.getenv('MYSQL_PORT', '3306')
MYSQL_DB = os.getenv('MYSQL_DB', 'immune_data_platform')

# 构建数据库连接URI
SQLALCHEMY_DATABASE_URI = (
    f"mysql+pymysql://{MYSQL_USER}:{MYSQL_PASS}"
    f"@{MYSQL_HOST}:{MYSQL_PORT}/{MYSQL_DB}"
    "?charset=utf8mb4"
)

# 创建数据库引擎
engine = create_engine(SQLALCHEMY_DATABASE_URI, echo=True)

# 创建数据库会话工厂
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)

# 创建基础模型类
Base = declarative_base()

# 用户模型
class User(Base):
    """
    用户模型
    用于存储用户基本信息、认证信息和权限信息
    """
    __tablename__ = "users"  # 表名
    
    # 用户ID，主键，自动递增
    id = Column(Integer, primary_key=True, index=True)
    # 用户名，唯一，用于登录
    username = Column(String(50), unique=True, index=True, nullable=False)
    # 邮箱，唯一
    email = Column(String(100), unique=True, index=True, nullable=False)
    # 加密后的密码
    hashed_password = Column(String(100), nullable=False)
    # 用户角色，如admin, researcher等
    role = Column(String(20), default="researcher")
    # 用户状态，1为激活，0为禁用
    is_active = Column(Integer, default=1)
    # 创建时间
    created_at = Column(DateTime, default=datetime.utcnow)
    # 更新时间
    updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
    
    def __repr__(self):
        """
        返回用户对象的字符串表示
        """
        return f'<User {self.username}>'

# 文件模型
class File(Base):
    """
    文件模型
    用于存储文件的元数据信息
    """
    __tablename__ = "files"  # 表名
    
    # 文件ID，主键，自动递增
    id = Column(Integer, primary_key=True, index=True)
    # 原始文件名
    filename = Column(String(255), nullable=False)
    # 文件存储路径
    filepath = Column(String(500), nullable=False)
    # 文件大小（字节）
    filesize = Column(Integer, nullable=False)
    # 文件类型（MIME类型）
    filetype = Column(String(50), nullable=False)
    # 文件版本号
    version = Column(Float, default=1.0)
    # 关联的用户ID
    user_id = Column(Integer, nullable=False)
    # 文件描述
    description = Column(Text)
    # 软删除标记，0为未删除，1为已删除
    is_deleted = Column(Integer, default=0)
    # 创建时间
    created_at = Column(DateTime, default=datetime.utcnow)
    # 更新时间
    updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
    
    def __repr__(self):
        """
        返回文件对象的字符串表示
        """
        return f'<File {self.filename}>'

# 工作流模型
class Workflow(Base):
    """
    工作流模型
    用于存储工作流的配置信息
    """
    __tablename__ = "workflows"  # 表名
    
    # 工作流ID，主键，自动递增
    id = Column(Integer, primary_key=True, index=True)
    # 工作流名称
    name = Column(String(100), nullable=False)
    # 工作流描述
    description = Column(Text)
    # 关联的用户ID
    user_id = Column(Integer, nullable=False)
    # 工作流配置信息（JSON格式）
    config = Column(Text)
    # 创建时间
    created_at = Column(DateTime, default=datetime.utcnow)
    # 更新时间
    updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
    
    def __repr__(self):
        """
        返回工作流对象的字符串表示
        """
        return f'<Workflow {self.name}>'

# 结果模型
class Result(Base):
    """
    结果模型
    用于存储分析结果数据
    """
    __tablename__ = "results"  # 表名
    
    # 结果ID，主键，自动递增
    id = Column(Integer, primary_key=True, index=True)
    # 结果名称
    name = Column(String(100), nullable=False)
    # 关联的工作流ID
    workflow_id = Column(Integer, nullable=False)
    # 关联的用户ID
    user_id = Column(Integer, nullable=False)
    # 结果数据（JSON格式）
    data = Column(Text)
    # 结果状态 ("pending", "processing", "completed", "failed")
    status = Column(String(20), default="completed")
    # 结果描述
    description = Column(Text)
    # 是否公开（0-私有，1-公开）
    is_public = Column(Integer, default=0)
    # 创建时间
    created_at = Column(DateTime, default=datetime.utcnow)
    # 更新时间
    updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
    
    def __repr__(self):
        """
        返回结果对象的字符串表示
        """
        return f'<Result {self.name}>'

# 结果分享模型
class ResultShare(Base):
    """
    结果分享模型
    用于存储结果分享信息
    """
    __tablename__ = "result_shares"  # 表名
    
    # 分享ID，主键，自动递增
    id = Column(Integer, primary_key=True, index=True)
    # 结果ID
    result_id = Column(Integer, nullable=False)
    # 分享者用户ID
    sharer_id = Column(Integer, nullable=False)
    # 被分享者用户ID
    shared_with_id = Column(Integer, nullable=False)
    # 权限级别 ("read", "write")
    permission = Column(String(10), default="read")
    # 创建时间
    created_at = Column(DateTime, default=datetime.utcnow)
    # 更新时间
    updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
    
    def __repr__(self):
        """
        返回结果分享对象的字符串表示
        """
        return f'<ResultShare result_id={self.result_id} shared_with_id={self.shared_with_id}>'

# 角色模型
class Role(Base):
    """
    角色模型
    用于存储系统中的角色信息
    """
    __tablename__ = "roles"  # 表名
    
    # 角色ID，主键，自动递增
    id = Column(Integer, primary_key=True, index=True)
    # 角色名称，唯一
    name = Column(String(20), unique=True, nullable=False)
    # 角色描述
    description = Column(String(100))
    
    def __repr__(self):
        """
        返回角色对象的字符串表示
        """
        return f'<Role {self.name}>'

# 权限模型
class Permission(Base):
    """
    权限模型
    用于存储系统中的权限信息
    """
    __tablename__ = "permissions"  # 表名
    
    # 权限ID，主键，自动递增
    id = Column(Integer, primary_key=True, index=True)
    # 权限名称，唯一
    name = Column(String(50), unique=True, nullable=False)
    # 权限描述
    description = Column(String(100))
    
    def __repr__(self):
        """
        返回权限对象的字符串表示
        """
        return f'<Permission {self.name}>'

# 角色权限关联模型
class RolePermission(Base):
    """
    角色权限关联模型
    用于存储角色和权限的多对多关联关系
    """
    __tablename__ = "role_permissions"  # 表名
    
    # 关联ID，主键，自动递增
    id = Column(Integer, primary_key=True, index=True)
    # 角色ID
    role_id = Column(Integer, nullable=False)
    # 权限ID
    permission_id = Column(Integer, nullable=False)
    
    def __repr__(self):
        """
        返回角色权限关联对象的字符串表示
        """
        return f'<RolePermission role_id={self.role_id} permission_id={self.permission_id}>'

# 工作流模板模型
class WorkflowTemplate(Base):
    """
    工作流模板模型
    用于存储可复用的工作流模板
    """
    __tablename__ = "workflow_templates"  # 表名
    
    # 模板ID，主键，自动递增
    id = Column(Integer, primary_key=True, index=True)
    # 模板名称
    name = Column(String(100), nullable=False)
    # 模板描述
    description = Column(Text)
    # 关联的用户ID
    user_id = Column(Integer, nullable=False)
    # 模板配置信息（JSON格式）
    config = Column(Text)
    # 是否公开模板（0-私有，1-公开）
    is_public = Column(Integer, default=0)
    # 创建时间
    created_at = Column(DateTime, default=datetime.utcnow)
    # 更新时间
    updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
    
    def __repr__(self):
        """
        返回工作流模板对象的字符串表示
        """
        return f'<WorkflowTemplate {self.name}>'

# 工作流执行历史模型
class WorkflowExecution(Base):
    """
    工作流执行历史模型
    用于存储工作流执行的历史记录和状态
    """
    __tablename__ = "workflow_executions"  # 表名
    
    # 执行记录ID，主键，自动递增
    id = Column(Integer, primary_key=True, index=True)
    # 关联的工作流ID
    workflow_id = Column(Integer, nullable=False)
    # 执行状态（pending, running, completed, failed）
    status = Column(String(20), default="pending")
    # 执行开始时间
    started_at = Column(DateTime)
    # 执行结束时间
    finished_at = Column(DateTime)
    # 执行日志
    logs = Column(Text)
    # 执行结果数据（JSON格式）
    result_data = Column(Text)
    # 创建时间
    created_at = Column(DateTime, default=datetime.utcnow)
    # 更新时间
    updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
    
    def __repr__(self):
        """
        返回工作流执行历史对象的字符串表示
        """
        return f'<WorkflowExecution workflow_id={self.workflow_id} status={self.status}>'

# 系统配置模型
class SystemConfig(Base):
    """
    系统配置模型
    用于存储系统级别的配置信息
    """
    __tablename__ = "system_configs"  # 表名
    
    # 配置ID，主键，自动递增
    id = Column(Integer, primary_key=True, index=True)
    # 配置键
    key = Column(String(100), unique=True, nullable=False)
    # 配置值
    value = Column(Text)
    # 配置描述
    description = Column(String(255))
    # 创建时间
    created_at = Column(DateTime, default=datetime.utcnow)
    # 更新时间
    updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
    
    def __repr__(self):
        """
        返回系统配置对象的字符串表示
        """
        return f'<SystemConfig {self.key}>'

# 操作日志模型
class OperationLog(Base):
    """
    操作日志模型
    用于记录用户操作日志
    """
    __tablename__ = "operation_logs"  # 表名
    
    # 日志ID，主键，自动递增
    id = Column(Integer, primary_key=True, index=True)
    # 用户ID
    user_id = Column(Integer, nullable=False)
    # 用户名
    username = Column(String(50), nullable=False)
    # 操作类型
    operation_type = Column(String(50), nullable=False)
    # 操作描述
    description = Column(Text)
    # 请求方法
    method = Column(String(10))
    # 请求路径
    path = Column(String(255))
    # 请求参数
    params = Column(Text)
    # 响应状态码
    status_code = Column(Integer)
    # IP地址
    ip_address = Column(String(45))
    # 用户代理
    user_agent = Column(Text)
    # 创建时间
    created_at = Column(DateTime, default=datetime.utcnow)
    
    def __repr__(self):
        """
        返回操作日志对象的字符串表示
        """
        return f'<OperationLog {self.username} {self.operation_type}>'

# 数据库会话依赖
def get_db():
    """
    获取数据库会话依赖
    用于FastAPI的依赖注入系统
    Yields:
        Session: 数据库会话对象
    """
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()